package http_server

import (
	"log"
	"net/http"
	"strings"
)

type RouterGroup struct {
	prefix string // 前缀路径(分组路径，例如 /api/v1)

	middlewares []HandlerFunc
	parent      *RouterGroup
	engine      *Engine
}

func (g *RouterGroup) Group(prefix string) *RouterGroup {
	engine := g.engine
	newGroup := &RouterGroup{
		prefix: g.prefix + prefix,
		parent: g,
		engine: engine,
	}
	engine.groups = append(engine.groups, newGroup)
	return newGroup
}

type router struct {
	roots    map[string]*node
	handlers map[string]HandlerFunc
}

func newRouter() *router {
	return &router{
		roots:    make(map[string]*node),
		handlers: make(map[string]HandlerFunc),
	}
}

// parsePattern 切割
func parsePattern(pattern string) []string {
	routers := strings.Split(pattern, "/")
	parts := make([]string, 0)
	for _, item := range routers {
		if item != "" {
			parts = append(parts, item)
			if item == "*" {
				break
			}
		}
	}

	return parts
}

// addRoute 添加路由
func (r *router) addRoute(method string, pattern string, handler HandlerFunc) {
	parts := parsePattern(pattern)
	key := method + "-" + pattern
	_, ok := r.roots[method]
	if !ok {
		r.roots[method] = &node{}
	}
	r.roots[method].inster(pattern, parts, 0)
	log.Printf("%s \n", key)
	r.handlers[key] = handler
}

func (group *RouterGroup) addRoute(method string, comp string, handler HandlerFunc) {
	pattern := group.prefix + comp
	group.engine.router.addRoute(method, pattern, handler)
}

func (r *router) getRoute(method string, path string) (*node, map[string]string) {
	searchParts := parsePattern(path) // 切割路径参数
	params := make(map[string]string)
	root, ok := r.roots[method]
	if !ok {
		return nil, nil
	}
	n := root.search(searchParts, 0)
	if n != nil {
		parts := parsePattern(n.pattern)
		for index, part := range parts {
			if part[0] == ':' {
				params[part[1:]] = searchParts[index]
			}
			if part[0] == '*' && len(part) > 1 {
				params[part[1:]] = strings.Join(searchParts[index:], "/")
				break
			}
		}
		return n, params
	}
	return nil, nil

}
func (r *router) handle(ctx *Context) {
	n, params := r.getRoute(ctx.R.Method, ctx.R.URL.Path)
	if n != nil {
		key := ctx.R.Method + "-" + n.pattern

		ctx.Params = params
		// 匹配对应路由的中间件
		ctx.handlers = append(ctx.handlers, r.handlers[key])
	} else {
		ctx.handlers = append(ctx.handlers, func(ctx *Context) {
			ctx.W.WriteHeader(http.StatusNotFound)
			ctx.W.Write([]byte("404 NOT FOUND\n"))
		})

	}
	ctx.Next()

}
